package com.lhl.aliyun.autoconfigure.oss;

import java.io.File;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.model.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import com.aliyun.oss.OSSClient;

import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class OssFileUtil {

    private final String ossPIX = "https://qipai7.oss-cn-shanghai.aliyuncs.com/";
    private OSSClient ossClient;
    private OssProperties ossProperties;

    public OssFileUtil(OSSClient ossClient, OssProperties ossProperties) {
        this.ossClient = ossClient;
        this.ossProperties = ossProperties;
    }

    /**
     * 文件上传
     * 
     * @param myKey
     * @param file
     *            要上传的文件
     */
    public String upLoadFileToALiyun(String myKey, File file) {

        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();
        // 设置上传内容类型
        // meta.setContentType(contentType);
        // 设置上传文件长度
        meta.setContentLength(file.length());
        // 上传文件
        ossClient.putObject(ossProperties.getBucketName(), myKey, file, meta);
        // 返回地址
        return ossPIX + myKey;

    }

    /**
     *
     * @param fileUrl
     * @param tempFile
     * @return
     * @throws Exception
     */
    public File downloadFileFromALiyun(String fileUrl, String tempFile) throws Exception {
        String myKey = filePathName(URLDecoder.decode(fileUrl, "UTF-8"));
        // 下载object到文件
        log.debug("myKey=={}", myKey);
        log.debug("tempFile=={}", tempFile);
        log.debug("ossProperties.getBucketName()=={}", ossProperties.getBucketName());
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        // File f = new File(tempFile);
        // ossClient.getObject(new GetObjectRequest(ossProperties.getBucketName(), myKey), f);
        OSSObject ossObject = ossClient.getObject(new GetObjectRequest(ossProperties.getBucketName(), myKey));
        @Cleanup
        InputStream inputStream = ossObject.getObjectContent();
        File f = new File(tempFile);
        FileUtils.copyInputStreamToFile(inputStream, f);
        return f;
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        // return f;
    }

    public File downloadFileFromALiyun2(String fileUrl, String tempFile) throws Throwable {
        log.debug("fileUrl=={}", fileUrl);
        log.debug("tempFile=={}", tempFile);
        String myKey = filePathName(URLDecoder.decode(fileUrl, "UTF-8"));
        // 下载请求，10个任务并发下载，启动断点续传。
        DownloadFileRequest downloadFileRequest = new DownloadFileRequest(ossProperties.getBucketName(), myKey);
        downloadFileRequest.setDownloadFile(tempFile);
        downloadFileRequest.setPartSize(1 * 1024 * 1024);
        downloadFileRequest.setTaskNum(10);
        downloadFileRequest.setEnableCheckpoint(true);
        downloadFileRequest.setCheckpointFile(tempFile);

        // 下载文件。
        DownloadFileResult downloadRes = ossClient.downloadFile(downloadFileRequest);
        // 下载成功时，会返回文件元信息。
        downloadRes.getObjectMetadata();
        return new File(tempFile);
    }

    /**
     * 获得文件key
     * 
     * @param fileUrl
     * @return
     */
    private String filePathName(String fileUrl) {
        return StringUtils.remove(fileUrl, ossPIX);
    }

    /**
     * 获得oss目录下所有的文件列表
     * @param var1 bucketName
     * @param var2 文件前缀 文件夹路径
     * @return
     */
    public List<String> listObjectsV2(String var1, String var2) {
        ListObjectsV2Result result = ossClient.listObjectsV2(var1,var2);
        List<OSSObjectSummary> ossObjectSummaries = result.getObjectSummaries();
        List<String> files = ossObjectSummaries.stream().map(o -> o.getKey()).collect(Collectors.toList());
        log.debug("pics=={}",files);
        return ossObjectSummaries.stream().filter(x->(StrUtil.endWithAnyIgnoreCase(x.getKey(),".jpg")
                || StrUtil.endWithAnyIgnoreCase(x.getKey(),".png"))).map(x->x.getKey()).collect(Collectors.toList());
    }

    public OSSClient getOSSClient(){
        return ossClient;
    }
}
